/*
 * @filename CustomInvocationSecurityMetadataSourceService.java
 * @author yinqi
 * @version 0.0.1
 * @date 2017年8月1日
 */
package com.bnzj.core.web.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;


/**
 * 最核心的地方，就是提供某个资源对应的权限定义，即getAttributes方法返回的结果。 此类在初始化时，应该取到所有资源及其对应角色的定义。 
 * @author yinqi
 */
public class CustomInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {
    
    private SecurityResourceManager securityManager;
    
    /* (non-Javadoc)
     * @see org.springframework.security.access.SecurityMetadataSource#getAttributes(java.lang.Object)
     */
    /**
     * 根据URL，找到相关的权限配置
     */
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
        // object 是一个被用户请求的url
        FilterInvocation filterInvocation = (FilterInvocation) object;
        if (securityManager.getResourceMap() == null) {
            throw new IllegalArgumentException("没有资源");
        }
        for (Entry<String, Set<ConfigAttribute>> entry : securityManager.getResourceMap().entrySet()) {
            RequestMatcher requestMatcher = new AntPathRequestMatcher(entry.getKey());
            if (requestMatcher.matches(filterInvocation.getHttpRequest())) {
                return entry.getValue();
            }
        }
        //没有被管理起来的都是可匿名访问的就返回null
        //return null;
        //如果没被管理起来的都不可访问，就返回一个集合
        return securityManager.getBasicRoleSet();
    }

    /* (non-Javadoc)
     * @see org.springframework.security.access.SecurityMetadataSource#getAllConfigAttributes()
     */
    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return new ArrayList<ConfigAttribute>();
    }

    /* (non-Javadoc)
     * @see org.springframework.security.access.SecurityMetadataSource#supports(java.lang.Class)
     */
    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}
